﻿namespace UnitTest.Dxp.Orm.DocDB

open System
open Microsoft.VisualStudio.TestTools.UnitTesting
open Lib.Dxp.Core
open Lib.Dxp.Orm
open Lib.Dxp.Orm.Dsl
open Lib.Dxp.Orm.DataValueInit

type RoleExt = { A : string; B : int; C : decimal }

[<FlagsAttribute>]
type IFLAG = | A = 0 | B = 1 | C = 2

type UnitTest private () = 
        inherit ExtTable()
        static member ctor with get() = let x = UnitTest() in x.init(); x
        member val      Login = varchar 50  with get
        member val      Passw = varchar 50  with get
        member val       Flag = int ()      with get
        member val   FullName = dyn ""      with get
        member val   RolesId  = dyn [1]     with get
        member val   RoleExt  = dyn [] : DataValue<RoleExt list>     with get
        member val   RoleMex  = dyn [] : DataValue<(string list * int * decimal * RoleExt) list>     with get


[<TestClass>]
type UnitTest_DxpCoreText() = 

    let pretty t = t |> trim |> splitRe "[\s\r\n]+" |> " ".join
    

    [<TestMethod>]
    member x.CheckCombinedSelect () = 
        let u = UnitTest.ctor
        let q = cmd_select [ select [ u.Login ; u.FullName; u.RolesId ]
                             where(u.Id <=. 100) ]
                |> UnitTest.Dxp.Orm.Dsl.Debug.SqlCommand.asLogInfo
        let expect = @"
QRY
SELECT UnitTest.Login AS 'Login', 
       (SELECT ValueT FROM UnitTest_Ext WHERE ObjectId = UnitTest.Id AND FieldName = 'FullName') AS 'FullName', 
       (SELECT ValueT FROM UnitTest_Ext WHERE ObjectId = UnitTest.Id AND FieldName = 'RolesId') AS 'RolesId' 
       FROM UnitTest WHERE ( (UnitTest.Id <= @a1) ) 
`@a1`=`100`"
        Assert.AreEqual(pretty expect, pretty q)


    [<TestMethod>]
    member x.AllinOneTwo () = 
        let tstLogin = "test8"
        let o = UnitTest.ctor
        for id in o.find(o.Login ==. tstLogin) do 
            o.load(unbox id); o.delete() 
        let o = UnitTest.ctor
        o.Login.Value <- "test8"
        o.Passw.Value <- "azxs"
        //o.Flag.Value <- IFLAG.B
        o.RolesId.Value <- [10..15]
        o.RoleExt.Value <- [ { A = "aaa"; B = 23; C = 11.01m }
                             { A = "a5a"; B = 53; C = 51.01m } ]
        let i = o.save() 
        Assert.AreEqual(true, i > 0)
        //Assert.AreEqual(true, IFLAG.B = o.Flag.Value)

        let m = UnitTest.ctor
        m.load i
        Assert.AreEqual("test8", m.Login.Value)
        Assert.AreEqual("azxs",  m.Passw.Value)
        //Assert.AreEqual(IFLAG.B, m.Flag.Value)
        Assert.AreEqual([10..15],  m.RolesId.Value)
        Assert.AreEqual([ { A = "aaa"; B = 23; C = 11.01m }
                          { A = "a5a"; B = 53; C = 51.01m } ],  m.RoleExt.Value)


    [<TestMethod>]
    member x.AllinOneThree () = 
        let tstLogin = "test8"
        let o = UnitTest.ctor
        for id in o.find(o.Login ==. tstLogin) do 
            o.load(unbox id); o.delete() 
        let o = UnitTest.ctor
        o.Login.Value <- "test8"
        o.Passw.Value <- "azxs"
        o.RolesId.Value <- [10..15]
        o.RoleMex.Value <- [ ( ["aa\'a"; "xs"], 23, 11.01m, { A = "aaa"; B = 23; C = 11.01m} )
                             ( ["a\"5a"; "xs"], 53, 51.01m, { A = "a5a"; B = 53; C = 51.01m} ) ]
        Assert.AreEqual(true, (0 = o.Id.Value))
        let i = o.save() 
        Assert.AreEqual(true, i > 0)
        Assert.AreEqual(true, (i = o.Id.Value))

        let m = UnitTest.ctor
        m.load i
        Assert.AreEqual("test8", m.Login.Value)
        Assert.AreEqual("azxs",  m.Passw.Value)
        Assert.AreEqual([10..15],  m.RolesId.Value)
        Assert.AreEqual([ ( ["aa\'a"; "xs"], 23, 11.01m, { A = "aaa"; B = 23; C = 11.01m} )
                          ( ["a\"5a"; "xs"], 53, 51.01m, { A = "a5a"; B = 53; C = 51.01m} ) ],  m.RoleMex.Value)



    [<TestMethod>]
    member x.AllinOne () = 
        let tstLogin = "test8"

        let o = UnitTest.ctor
        for id in o.find(o.Login ==. tstLogin) do 
            o.load(unbox id); o.delete() 
        
        // Create object
        let o = UnitTest.ctor
        o.Login.Value <- "test8"
        o.Passw.Value <- "azxs"
        o.RolesId.Value <- [0..5]
        let i = o.save() 
        Assert.AreEqual(true, i > 0)

        // Load object
        let m = UnitTest.ctor
        m.load i
        Assert.AreEqual("test8", m.Login.Value)
        Assert.AreEqual("azxs",  m.Passw.Value)
        Assert.AreEqual([0..5],  m.RolesId.Value)

        // Update object
        o.RolesId.Value <- [7..8]
        o.FullName.Value <- "full"
        o.Login.Value <- "new login"
        let i = o.save() 

        let m = UnitTest.ctor
        let xs = m.find(o.FullName ==. "fulla")
        Assert.AreEqual(1,  List.length xs)

        let m = UnitTest.ctor
        m.load i
        Assert.AreEqual("new login", m.Login.Value)
        Assert.AreEqual("azxs",  m.Passw.Value)
        Assert.AreEqual([7..8],  m.RolesId.Value)
        
        m.delete()
